/* 
 * Licensed Materials - Property of IBM
 * (c) Copyright IBM Corporation 2010. All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:  Use,
 * duplication or disclosure restricted by GSA ADP Schedule
 * Contract with IBM Corp.
 *
 * This code is released under the terms of the Eclipse Public License
 * version 1.0 which can be found at the top level of this project or
 * or at http://www.eclipse.org/org/documents/epl-v10.php
 */

package com.ibm.mining;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.core.runtime.IProgressMonitor;

import com.ibm.team.filesystem.client.internal.content.FileContentManager;
import com.ibm.team.links.client.ILinkManager;
import com.ibm.team.repository.client.IItemManager;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.util.IClientLibraryContext;
import com.ibm.team.repository.common.IAuditableHandle;
import com.ibm.team.repository.common.IItem;
import com.ibm.team.repository.common.IItemHandle;
import com.ibm.team.repository.common.IManagedItemHandle;
import com.ibm.team.repository.common.ItemNotFoundException;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.scm.client.IVersionableManager;
import com.ibm.team.scm.client.IWorkspaceManager;
import com.ibm.team.scm.client.SCMPlatform;
import com.ibm.team.scm.common.IBaseline;
import com.ibm.team.scm.common.IRepositoryProgressMonitor;
import com.ibm.team.scm.common.IScmService;
import com.ibm.team.scm.common.IVersionable;
import com.ibm.team.scm.common.IVersionableHandle;
import com.ibm.team.scm.common.dto.IAncestorReport;
import com.ibm.team.scm.common.dto.INameItemPair;
import com.ibm.team.scm.common.internal.dto.ServiceConfigurationProvider;

public class MinerServices {
	
	ITeamRepository repository;
	IProgressMonitor monitor;
	IWorkspaceManager workspaceManager;
	IScmService scmService;
	IRepositoryProgressMonitor repositoryProgressMonitor;
	IBaseline currentBaseline;
    ServiceConfigurationProvider currentServiceConfigurationProvider;
    ILinkManager linkManager;
    ResearchDatabase researchDatabase;
    
    public IRepositoryProgressMonitor getRepositoryProgressMonitor() {
		return repositoryProgressMonitor;
	}

	public void setRepositoryProgressMonitor(
			IRepositoryProgressMonitor repositoryProgressMonitor) {
		this.repositoryProgressMonitor = repositoryProgressMonitor;
	}

	public ResearchDatabase getResearchDatabase() {
		return researchDatabase;
	}

	public void setResearchDatabase(ResearchDatabase researchDatabase) {
		this.researchDatabase = researchDatabase;
	}

	public void setLinkManager(ILinkManager linkManager) {
		this.linkManager = linkManager;
	}

	Logger logger;
	
    public MinerServices() {
    }
    
	public ITeamRepository getRepository() {
		return repository;
	}
	
	public void setLogger(Logger logger) {
		this.logger = logger;
	}
	
	public void logException(Exception e) {
		StringWriter s = new StringWriter();
		//e.fillInStackTrace();
		e.printStackTrace(new PrintWriter(s));
		logger.severe("Uncaught exception during mining " + e + "\n" + s);
	}
	
	public void setRepository(ITeamRepository repository) {
		this.repository = repository;
    	scmService = (IScmService) ((IClientLibraryContext)repository).getServiceInterface(IScmService.class); 
		linkManager = (ILinkManager) repository.getClientLibrary(ILinkManager.class);
		workspaceManager = SCMPlatform.getWorkspaceManager(repository);
    	
	}
	
	public void setCurrentBaseline(IBaseline baseline) {
		currentBaseline = baseline;
    	currentServiceConfigurationProvider = ServiceConfigurationProvider.FACTORY.create(baseline);
	}
	
	public IWorkspaceManager getWorkspaceManager() {
		return workspaceManager;
	}
	public void setWorkspaceManager(IWorkspaceManager workspaceManager) {
		this.workspaceManager = workspaceManager;
	}
	public IProgressMonitor getMonitor() {
		return monitor;
	}
	public Logger getLogger() {
		return logger;
	}
	public ILinkManager getLinkManager() {
		return linkManager;
	}
	public void setMonitor(IProgressMonitor monitor) {
		this.monitor = monitor;
		repositoryProgressMonitor = IRepositoryProgressMonitor.ITEM_FACTORY.createItem(monitor);
	}
	
	public IItem getFullState(IItemHandle itemHandle)
			throws TeamRepositoryException {
		/* if the itemHandle is already an instance then just cast and return */
		logger.info("Get Full State Started...");
		if (itemHandle.hasFullState()) {
			return (IItem) itemHandle;
		}
		logger.info("Check point one...");
		try {
			// IVersionableHandle's are unmanaged, so we get them in a different
			// way
			if (itemHandle.isUnmanaged()) {
				logger.info("Item is Unmanaged");
				IVersionableManager versionableManager = workspaceManager
						.versionableManager();
				return versionableManager.fetchCompleteState(
						(IVersionableHandle) itemHandle, monitor);
			} else if (itemHandle instanceof IAuditableHandle
					&& itemHandle.getStateId() != null) {
				logger.info("Item is Auditable");
				return repository.itemManager().fetchCompleteState(
						(IAuditableHandle) itemHandle, monitor);
			} else {
				logger.info("Item is Other...");
				return repository.itemManager().fetchCompleteItem(itemHandle,
						IItemManager.DEFAULT, monitor);
			}
		} catch (ItemNotFoundException e) {
			String err = "Item not found in repository CLASS:"
					+ itemHandle.getClass().getCanonicalName() + " UUID:"
					+ itemHandle.getItemId().getUuidValue();
			logger.warning(err);
			return null;
		}
	}
	
	public String getPath(IVersionable versionable) throws TeamRepositoryException {
		String path = "/";
    	//IRepositoryProgressMonitor repositoryProgressMonitor = IRepositoryProgressMonitor.ITEM_FACTORY.createItem(monitor);
    	//ServiceConfigurationProvider scp = ServiceConfigurationProvider.FACTORY.create(currentBaseline);
    	
    	IAncestorReport ancestorReport = scmService.configurationLocateAncestors(currentServiceConfigurationProvider,
    			new IVersionableHandle[] {versionable}, null, repositoryProgressMonitor)[0];
    	
    	
    	for (INameItemPair pair : (List<INameItemPair>) ancestorReport.getNameItemPairs()) {
    		/* for now, don't worry about grabbing the versionable itself.  Just get the name */
    		//versionable = workspaceManager.versionableManager().fetchCompleteState(pa, monitor);
    		if (pair.getName() != null) {
    			path = path + "/" + pair.getName();
    		}
    	}
    	
	
    	if (path.length() < 2)
    	{
    		path += versionable.getName();
    	}
    	//indentedPrintf("path is %s\n", path);
    	return path;
    	
	}
	
	
}
